// Copyright (C) 2006 Taylor L. Riché <riche@cs.utexas.edu>
//  
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software 
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//

#ifndef IP6_PACKET_HH
#define IP6_PACKET_HH

#include <netinet/ip6.h>

#include <lagniappe/RData.h>
#include "Packet.hh"
#include "Eth_Packet.hh"

namespace pktTypes {

  const unsigned int IPv6_HSIZE = 0x28; // 40

  class IP6_Packet : public Eth_Packet
  {
  protected:
    ip6_hdr * ip6Hdr;
    payload_t ip6_payload;
  public:
    IP6_Packet() : ip6Hdr(NULL), ip6_payload(NULL) {}
    IP6_Packet(const Eth_Packet & pkt) : Eth_Packet(pkt)
    {
      assert(payload != NULL);
      ip6Hdr = (ip6_hdr *)eth_payload;
      ip6_payload = ((payload_t)ip6Hdr) + IPv6_HSIZE;
    }

    // Header getters and setters
    inline uint8_t getIPVersion() const {return (ip6Hdr->ip6_vfc & 0xF);}
    inline void setIPVersion() {ip6Hdr->ip6_flow = htonl(0x00000000); ip6Hdr->ip6_vfc = 0x60;}
    inline uint16_t getPayloadLength() const {return ntohs(ip6Hdr->ip6_plen);}
    inline void setPayloadLength(uint16_t pl) {ip6Hdr->ip6_plen = htons(pl);}
    inline uint8_t getNextHeader() {return ip6Hdr->ip6_nxt;}
    inline void setNextHeader(uint8_t nh) {ip6Hdr->ip6_nxt = nh;}
    inline uint8_t getHopLimit() {return ip6Hdr->ip6_hlim;}
    inline void setHopLimit(uint8_t hl) {ip6Hdr->ip6_hlim = hl;}
    inline in6_addr getSourceAddress() const {return ip6Hdr->ip6_src;}
    inline void setSourceAddress(in6_addr sa) {ip6Hdr->ip6_src = sa;}
    inline in6_addr getDestinationAddress() const {return ip6Hdr->ip6_dst;}
    inline void setDestinationAddress(in6_addr da) {ip6Hdr->ip6_dst = da;}
  };

}

#endif // IP6_PACKET_HH
